package com.google.code.sip.ucenter.imports;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.google.code.sip.core.utils.ReflectionUtils;
import com.google.code.sip.ucenter.converter.ConverterUtils;

public abstract class AbstractImporter<T> implements Importer {
	protected String dataPath = "/config/data/init/";
	protected static final String ROOT = "dataset";
	protected Class<T> entityClass;
	private String xmlFile;
	protected BeanUtilsBean beanUtilsBean = BeanUtilsBean.getInstance();
	static {
		ConverterUtils.registConverter();
	}

	public AbstractImporter() {
		entityClass = ReflectionUtils.getSuperClassGenricType(getClass());
		String xmlFilename = StringUtils.uncapitalize(entityClass
				.getSimpleName());
		xmlFile = xmlFilename + ".xml";
	}

	public AbstractImporter(String xmlFile) {
		entityClass = ReflectionUtils.getSuperClassGenricType(getClass());
		this.xmlFile = xmlFile;
	}

	public String getXmlFile() {
		return xmlFile;
	}

	public void setXmlFile(String xmlFile) {
		this.xmlFile = xmlFile;
	}

	@Override
	public void execute() throws Exception {
		doInit();
		List<T> entityes = loadEntities();
		if (entityes != null && !entityes.isEmpty()) {
			for (T entity : entityes) {
				doSave(entity);
			}
		}
	}

	protected Document getDocument() throws DocumentException {

		SAXReader reader = new SAXReader();
		return reader.read(this.getClass().getResourceAsStream(
				dataPath + xmlFile));

	}

	@SuppressWarnings("unchecked")
	protected List<T> loadEntities() throws DocumentException {
		Element rootElment = getDocument().getRootElement();
		List<Element> children = rootElment.elements();
		if (children != null && !children.isEmpty()) {
			List<T> entityes = new ArrayList<T>(children.size());
			for (Element child : children) {
				Map<String, String> model = new HashMap<String, String>(
						children.size());
				List<Element> props = child.elements();
				for (Element prop : props) {
					String name = prop.getName();
					String value = prop.getTextTrim();
					model.put(name, value);
				}
				entityes.add(toEntity(model));
			}
			return entityes;
		}
		return null;
	}

	protected String getElementText(Element child, String elementName) {
		return child.element(elementName).getTextTrim();
	}

	protected abstract T toEntity(Map<String, String> props);

	protected abstract void doSave(T entity);

	protected abstract void doInit();
}
